27. 移除元素

27. 移除元素

分析

题目中提到的要原地移除所有数值,说明只能通过覆盖的方式来移动元素,同时返回的内容是 nums 中与 val 不同的元素的数量,这个就很明显了,如果你知道双指针法的话,这里就只用返回慢指针即可。
对于双指针法,我们要明确指针的定义:

解题

public int removeElement(int[] nums, int val) {
    int slow=0,fast=0;
    for(;fast<nums.length;fast++){
        // 元素与目标值相等的时候,需要同时移动快慢指针,不相等的时候,只需要移动快指针,慢指针不动
        if(nums[fast]!=val){
            nums[slow]=nums[fast];
            slow++;
        }
    }
    //slow 指的是下一个非val元素插入的位置的索引,而非val元素个数,应该是 slow-1+1 
    // 所以这里直接返回 slow 即可
    return slow;
}

双指针法为什么比两层 for 循环快

双层 for 循环的时候,检测到一次相同元素就会把后续所有元素都往前移动一个位置,不仅存在多余的操作(如果此元素后面也存在目标元素,那目标元素以及后面的元素的的移动就是没有必要的)而且移动效率太低,一次只能移动一格;双指针法没有这些多余操作,只移动一个元素,而且效率很高(直接从之前的位置,到最终的位置,移动之后不会再移动),所以双指针法快
双指针法(快慢指针法)在数组和链表的操作中是非常常见的,很多考察数组、链表、字符串等操作的面试题,都使用双指针法。
只要是要求在原数组上移除元素的,几乎都是用双指针

相关题

26. 删除有序数组中的重复项
283. 移动零
844. 比较含退格的字符串
977. 有序数组的平方
滑动窗口
209. 长度最小的子数组
904. 水果成篮